// Copyright (C) 1953-2023 NUDT
// Verilog module name - traffic_receive_and_recognition 
// Version: V4.3.0.20230901
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
///////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ps
module traffic_receive_and_recognition(
input                 i_clk,
input                 i_rst_n,
input      [79:0]     iv_localclk,
input      [8:0]      iv_data,
input                 i_data_wr, 
input                 i_teststart_en,

output reg [31:0]     ov_flowA_discard_counter,  
output reg [31:0]     ov_flowB_discard_counter,  
output reg [31:0]     ov_flowC_discard_counter, 
output reg [2:0]      ov_pktin_pulse,  
output reg [63:0]     ov_flowA_transdelay,  
output reg [63:0]     ov_flowB_transdelay,  
output reg [63:0]     ov_flowC_transdelay,
output reg            o_flowA_delay_wr,
output reg            o_flowB_delay_wr,
output reg            o_flowC_delay_wr
);         

reg       [10:0]       rv_rev_cycle_cnt;
reg       [31:0]       rv_flowA_receive_counter;
reg       [31:0]       rv_flowB_receive_counter;
reg       [31:0]       rv_flowC_receive_counter;
reg       [79:0]       rv_syn_sendtime ;

reg       [111:0]      rv_pkt_data;

always@(posedge i_clk or negedge i_rst_n)begin 
    if(!i_rst_n) begin
		rv_pkt_data       <=112'd0;
		rv_rev_cycle_cnt  <=11'd0;
    end
    else begin	
		if(i_data_wr==1'b1)begin
			rv_pkt_data      <= {rv_pkt_data[103:0],iv_data[7:0]};
			rv_rev_cycle_cnt <= rv_rev_cycle_cnt +1'b1;  
			
		end	
		else begin
			rv_pkt_data      <= {rv_pkt_data[103:0],8'b0};
			rv_rev_cycle_cnt <=11'd0;		
		end
    end       
end	

reg       [2:0]     trr_state;
localparam          INIT_S         = 3'd0,
					IDLE_S         = 3'd1,
					RCV_PKTA_S     = 3'd2,
					RCV_PKTB_S     = 3'd3,
                    RCV_PKTC_S     = 3'd4;

always@(posedge i_clk or negedge i_rst_n)begin 
    if(!i_rst_n) begin
		 ov_pktin_pulse     <= 3'b0;
		 ov_flowA_discard_counter <=32'b0;  
         ov_flowB_discard_counter <=32'b0;  
         ov_flowC_discard_counter <=32'b0; 
		 rv_flowA_receive_counter <=32'b0;
		 rv_flowB_receive_counter <=32'b0;
		 rv_flowC_receive_counter <=32'b0;
		 
         ov_flowA_transdelay      <=64'b0; 
		 ov_flowB_transdelay      <=64'b0; 
		 ov_flowC_transdelay      <=64'b0;
		 o_flowA_delay_wr    <=1'b0;
         o_flowB_delay_wr    <=1'b0;
		 o_flowC_delay_wr    <=1'b0;
		 rv_syn_sendtime    <=80'd0;
         trr_state          <=INIT_S;
    end
    else begin
        case(trr_state)
		INIT_S:begin
			ov_pktin_pulse     <= 3'b0;
			ov_flowA_discard_counter <=32'b0;  
			ov_flowB_discard_counter <=32'b0;  
			ov_flowC_discard_counter <=32'b0; 
			rv_flowA_receive_counter <=32'b0;
			rv_flowB_receive_counter <=32'b0;
			rv_flowC_receive_counter <=32'b0;			
			ov_flowA_transdelay      <=64'b0; 
			ov_flowB_transdelay      <=64'b0; 
			ov_flowC_transdelay      <=64'b0;
			o_flowA_delay_wr    <=1'b0;
			o_flowB_delay_wr    <=1'b0;
			o_flowC_delay_wr    <=1'b0;
			rv_syn_sendtime    <=80'd0;
			if(i_teststart_en ==1'b1)begin
				trr_state      <=IDLE_S;
			end			
			else begin
				trr_state      <=INIT_S;
			end
		end
        IDLE_S:begin  		
			if(rv_rev_cycle_cnt ==11'd6)begin
				if(rv_pkt_data[47:0]==48'haa0000000002)begin          				
					rv_flowA_receive_counter   <= rv_flowA_receive_counter +1'b1;
					rv_syn_sendtime   <= iv_localclk;
					ov_pktin_pulse[0] <=1'd1;
					trr_state         <=RCV_PKTA_S;
				end
				else if(rv_pkt_data[47:0]==48'hbb0000000003)begin          				
					rv_flowB_receive_counter   <= rv_flowB_receive_counter +1'b1;
					rv_syn_sendtime   <= iv_localclk;
					ov_pktin_pulse[1] <=1'd1;
					trr_state         <=RCV_PKTB_S;
				end
				else if(rv_pkt_data[47:0]==48'hcc0000000004)begin          				
					rv_flowC_receive_counter   <= rv_flowC_receive_counter +1'b1;
					rv_syn_sendtime   <= iv_localclk;
					ov_pktin_pulse[2] <=1'd1;
					trr_state         <=RCV_PKTC_S;
				end	
				else begin
					rv_flowA_receive_counter   <= rv_flowA_receive_counter;
					rv_flowB_receive_counter   <= rv_flowB_receive_counter;
					rv_flowC_receive_counter   <= rv_flowC_receive_counter;
					rv_syn_sendtime   <= 80'd0;
					ov_pktin_pulse    <= 3'b0;	
					trr_state         <=IDLE_S;
				end
				
			end
			else begin
				ov_flowA_discard_counter   <= ov_flowA_discard_counter;
				ov_flowB_discard_counter   <= ov_flowB_discard_counter;
				ov_flowC_discard_counter   <= ov_flowC_discard_counter;
				rv_flowA_receive_counter   <= rv_flowA_receive_counter;
				rv_flowB_receive_counter   <= rv_flowB_receive_counter;
				rv_flowC_receive_counter   <= rv_flowC_receive_counter;
				rv_syn_sendtime   <= rv_syn_sendtime;
				ov_pktin_pulse    <= 3'b0;
				ov_flowA_transdelay     <= 64'b0; 
				ov_flowB_transdelay     <= 64'b0; 
				ov_flowC_transdelay     <= 64'b0;
				o_flowA_delay_wr   <= 1'b0;
				o_flowB_delay_wr   <= 1'b0;
				o_flowC_delay_wr   <= 1'b0;				
				trr_state         <= IDLE_S;	
			end
        end
        RCV_PKTA_S:begin 
			if(rv_rev_cycle_cnt==11'd103)begin
				ov_flowA_discard_counter	  <= rv_pkt_data[111:80]-rv_flowA_receive_counter;
				ov_pktin_pulse[0] <= 1'd0;
				o_flowA_delay_wr   <= 1'b1;
				ov_flowA_transdelay[63:0] <= rv_syn_sendtime[63:0]-rv_pkt_data[63:0];
				if(i_teststart_en ==1'b1)begin
					trr_state      <=IDLE_S;
				end			
				else begin
					trr_state      <=INIT_S;
				end
			end
			else begin 
				ov_pktin_pulse[0] <=1'd0;
				o_flowA_delay_wr   <= 1'b0;
				ov_flowA_transdelay     <= 64'd0;
				ov_flowA_discard_counter     <= ov_flowA_discard_counter;
				trr_state         <= RCV_PKTA_S;			 		
			end
        end	 
        RCV_PKTB_S:begin 
			if(rv_rev_cycle_cnt==11'd103)begin
				ov_flowB_discard_counter	 	  <= rv_pkt_data[111:80]-rv_flowB_receive_counter;
				ov_pktin_pulse[1] <=1'd0;
				o_flowB_delay_wr   <= 1'b1;
				ov_flowB_transdelay[63:0] <= rv_syn_sendtime[63:0]-rv_pkt_data[63:0];
				if(i_teststart_en ==1'b1)begin
					trr_state      <=IDLE_S;
				end			
				else begin
					trr_state      <=INIT_S;
				end
			end
			else begin 
				ov_pktin_pulse[1] <=1'd0;
				o_flowB_delay_wr   <= 1'b0;
				ov_flowB_transdelay     <= 64'd0;
				ov_flowB_discard_counter       <= ov_flowB_discard_counter;
				trr_state         <= RCV_PKTB_S;			 		
			end			
        end	
        RCV_PKTC_S:begin 
			if(rv_rev_cycle_cnt==11'd103)begin
				ov_flowC_discard_counter	  <= rv_pkt_data[111:80]-rv_flowC_receive_counter;
				ov_pktin_pulse[2] <=1'd0;
				o_flowC_delay_wr   <= 1'b1;
				ov_flowC_transdelay[63:0] <= rv_syn_sendtime[63:0]-rv_pkt_data[63:0];
				if(i_teststart_en ==1'b1)begin
					trr_state      <=IDLE_S;
				end			
				else begin
					trr_state      <=INIT_S;
				end
			end
			else begin 
				ov_pktin_pulse[2] <=1'd0;
				o_flowC_delay_wr   <= 1'b0;
				ov_flowC_transdelay     <= 64'd0;
				ov_flowC_discard_counter     <= ov_flowC_discard_counter;
				trr_state         <= RCV_PKTC_S;			 		
			end				
        end			
        default:begin
			ov_pktin_pulse     <=3'b0;
			ov_flowA_discard_counter      <=32'b0;  
			ov_flowB_discard_counter      <=32'b0;  
			ov_flowC_discard_counter      <=32'b0; 
			ov_flowA_transdelay      <=64'b0; 
			ov_flowB_transdelay      <=64'b0; 
			ov_flowC_transdelay      <=64'b0;
			o_flowA_delay_wr    <=1'b0;
			o_flowB_delay_wr    <=1'b0;
			o_flowC_delay_wr    <=1'b0;
			rv_syn_sendtime    <=80'd0;
			trr_state          <=IDLE_S;	
		end   
		endcase
    end       
end
endmodule